<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Excel Editor</title>
    <link rel="stylesheet" href="https://unpkg.com/handsontable@latest/dist/handsontable.full.min.css">
    <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
    <script src="https://unpkg.com/handsontable@latest/dist/handsontable.full.min.js"></script>
</head>
<body>
<div id="app">
    <button onclick="loadFile()">Load Excel</button>
    <button onclick="saveFile()">Save Excel</button>
    <div id="excelTable" style="height: 400px; width: 100%;"></div>
</div>

<script>
    let hot;

    // 加载 Excel 文件
    function loadFile() {
        const input = document.createElement('input');
        input.type = 'file';
        input.accept = '.xlsx,.xls';
        input.onchange = (e) => {
            const file = e.target.files[0];
            if (!file) return;

            const reader = new FileReader();
            reader.onload = (event) => {
                const data = event.target.result;
                const workbook = XLSX.read(data, {type: 'binary'});
                const sheetName = workbook.SheetNames[0];
                const sheet = workbook.Sheets[sheetName];
                const json = XLSX.utils.sheet_to_json(sheet);
                const cols = getColumns(sheet);
                const rows = getRows(sheet);
                displayData(json, cols, rows);
            };
            reader.readAsBinaryString(file);
        };
        input.click();
    }

    // 获取列宽
    function getColumns(sheet) {
        const cols = [];
        const range = XLSX.utils.decode_range(sheet['!ref']);
        for (let C = range.s.c; C <= range.e.c; ++C) {
            const col = XLSX.utils.encode_col(C);
            const colInfo = sheet[col];
            if (colInfo && colInfo.wch) {
                cols.push({title: col, width: colInfo.wch * 10});
            } else {
                cols.push({title: col, width: 100});
            }
        }
        return cols;
    }

    // 获取行高
    function getRows(sheet) {
        const rows = [];
        const range = XLSX.utils.decode_range(sheet['!ref']);
        for (let R = range.s.r; R <= range.e.r; ++R) {
            const row = XLSX.utils.encode_row(R);
            const rowInfo = sheet[row];
            if (rowInfo && rowInfo.hpt) {
                rows.push({height: rowInfo.hpt * 10});
            } else {
                rows.push({height: 20});
            }
        }
        return rows;
    }

    // 渲染数据到 Handsontable
    function displayData(data, cols, rows) {
        const container = document.getElementById('excelTable');
        hot = new Handsontable(container, {
            data: data,
            columns: cols,
            manualColumnResize: true,
            manualRowResize: true,
            colHeaders: true,
            rowHeaders: true,
            licenseKey: 'non-commercial-and-evaluation', // 使用非商业许可证
            afterChange: function (change, source) {
                // 更新数据
                const newData = hot.getDataAtCell(change[0][0], change[0][1]);
                hot.setDataAtCell(change[0][0], change[0][1], newData);
            }
        });

        // 调整列宽和行高
        cols.forEach((col, index) => {
            hot.updateSettings({
                columns: cols
            });
            hot.colWidths[index] = col.width;
        });

        rows.forEach((row, index) => {
            hot.updateSettings({
                rows: rows
            });
            hot.rowHeights[index] = row.height;
        });
    }

    // 保存 Excel 文件
    function saveFile() {
        if (!hot) {
            alert('请先加载 Excel 文件');
            return;
        }
        const data = hot.getData();
        const workbook = XLSX.utils.book_new();
        const ws = XLSX.utils.json_to_sheet(data);
        XLSX.utils.book_append_sheet(workbook, ws, 'Sheet1');
        XLSX.writeFile(workbook, 'output.xlsx');
    }
</script>
</body>
</html>
